package cn.openea.perpartner.evaluation.web.service.impl;

import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.openea.perpartner.evaluation.web.entity.EvaluationSignup;
import cn.openea.perpartner.evaluation.web.entity.EvaluationTask;
import cn.openea.perpartner.evaluation.web.service.IEvaluationSignupService;
import cn.openea.perpartner.evaluation.web.service.ISendMsgService;
import cn.openea.perpartner.meily.constant.SystemConstants;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.TimerTask;

/**
 * @author rains
 * @since 2023-07-07 14:29
 */
@Slf4j
@Service("evaluationSendMsgService")
public class SendMsgServiceImpl implements ISendMsgService {

    @Value("${common.uri}")
    private String sendMsgUri;
    @Value("${meily.header.sysid}")
    private String sysId;
    @Value("${meily.header.syspwd}")
    private String sysPwd;
    @Resource
    private SystemConstants systemConstants;

    @Resource
    private IEvaluationSignupService evaluationSignupService;

    /**
     * 工单进度通知
     */
    private static final String WORKER_PROGRESS_TIP = "Zx2oCUdXO6VTXu_QddXdEZ-N8co5Z8UsudzFP6lbSEs";

    /**
     * 给参与者发送提交成果通知
     * @param signupInfo
     * @return
     */
    @Override
    public TimerTask partnerSubmitResult(EvaluationSignup signupInfo) {

        String nodeName= "提交成果";
        String first =  signupInfo.getSubject() + "的品牌推广任务已启动，请您在" + signupInfo.getEndTime() + "前（含当天）提交您的评测建议，验收通过后本次报酬将自动转入您的账户！";

        if(signupInfo.getReturnNum() < 3){
            if(signupInfo.getReturnNum() == 1){
                nodeName = "第" + signupInfo.getReturnNum() + "次返修";
                first = "您参与的" + signupInfo.getSubject() + "测评活动未能通过验收，请重新提交工作成果！（温馨提示：每人仅有2次返修机会。）";
            } else if(signupInfo.getReturnNum() == 2){
                nodeName = "第" + signupInfo.getReturnNum() + "次返修";
                first = "您参与的" + signupInfo.getSubject() + "测评活动未能通过验收，请重新提交工作成果！（温馨提示：您还有最后1次返修机会。）";
            }
        }

        // 公众号通知
        JSONObject paramsPartner = new JSONObject();
        paramsPartner.put("templateid", WORKER_PROGRESS_TIP);
        paramsPartner.put("first", first);
        paramsPartner.put("keyword1", "NO."+ signupInfo.getTaskNumber());// 工单号
        paramsPartner.put("keyword2", nodeName);// 工单进度
        paramsPartner.put("keyword3", signupInfo.getPartnerName());// 工单处理人
        paramsPartner.put("remark", "点击前往提交评测建议！温馨提示：接下来所开展的工作将在公众号以工单进度的方式通知到您，请务必持续关注公众号！");
        paramsPartner.put("pagepath", "/pages_private_scene1/evaluation/submit_results?docUnid="+ signupInfo.getId());// // （链接到【拍档提交成果】）
        paramsPartner.put("url", "/pages_private_scene1/evaluation/submit_results?docUnid="+ signupInfo.getId() + "&readOnly=1&userId=" + signupInfo.getPartnerId());// （链接到【拍档提交成果-只读】）
        paramsPartner.put("userid", signupInfo.getPartnerId());
        paramsPartner.put("docUnid", signupInfo.getId());
        paramsPartner.put("createdUserid", signupInfo.getPartnerId());
        return sendMsgToApplets(paramsPartner);
    }

    /**
     * 给发起人发送【用户参与】通知
     * @param evaluationTask
     * @param evaluationSignup
     * @return
     */
    @Override
    public TimerTask joinNotice(EvaluationTask evaluationTask, EvaluationSignup evaluationSignup) {
        Long joinQuota = evaluationSignupService.countQuota(new LambdaQueryWrapper<EvaluationSignup>()
                .eq(EvaluationSignup::getMainId, evaluationTask.getId())
                .notIn(EvaluationSignup::getStatus, "超时回收", "已回收"));
        Long remainQuota = 0l;
        if(joinQuota < evaluationTask.getQuota()){
            remainQuota = evaluationTask.getQuota() - joinQuota;
        }
        JSONObject paramsUser = new JSONObject();
        paramsUser.put("templateid", WORKER_PROGRESS_TIP);
        paramsUser.put("first", evaluationSignup.getPartnerName() + "已报名参与" + evaluationSignup.getSubject() + "的评测任务。当前评测名额剩余" + remainQuota + "名，本次品牌推广任务截止时间为" + evaluationSignup.getEndTime()+"。");
        paramsUser.put("keyword1", "NO."+ evaluationTask.getTaskNumber());// 工单号
        paramsUser.put("keyword2", "已有" + joinQuota + "人参与");// 工单进度
        paramsUser.put("keyword3", evaluationTask.getInitiatorName());// 工单处理人
        paramsUser.put("remark", "点击查看任务详情！温馨提示：分享给好友或微信群，让跟多小伙伴了解您的活动哦！");
        paramsUser.put("pagepath", "/pages_private_scene1/evaluation/sign_up?docUnid=" + evaluationTask.getId());// （链接到【报名页面】）
        paramsUser.put("url", "/pages_private_scene1/evaluation/sign_up?docUnid=" + evaluationTask.getId());// （链接到【报名页面】）
        paramsUser.put("userid", evaluationTask.getInitiatorId());
        paramsUser.put("docUnid", evaluationTask.getId());
        paramsUser.put("createdUserid", evaluationSignup.getPartnerId());
        return sendMsgToApplets(paramsUser);
    }

    /**
     * 给验收人发送【验收成果】通知
     * @param signupInfo
     * @return
     */
    @Override
    public TimerTask inspectorAcceptResult(EvaluationSignup signupInfo) {
        String nodeName = "验收成果";

        if(signupInfo.getReturnNum() < 3){
            if(signupInfo.getReturnNum() == 1){
                nodeName = "第" + signupInfo.getReturnNum() + "次修改";
            } else if(signupInfo.getReturnNum() == 2){
                nodeName = "第" + signupInfo.getReturnNum() + "次修改";
            }
        }

        JSONObject paramsInspector = new JSONObject();
        paramsInspector.put("templateid", WORKER_PROGRESS_TIP);
        paramsInspector.put("first", signupInfo.getPartnerName() + "已提交" + signupInfo.getSubject() + "的测评成果，请前往验收！");
        paramsInspector.put("keyword1", "NO."+ signupInfo.getTaskNumber());// 工单号
        paramsInspector.put("keyword2", nodeName);// 工单进度
        paramsInspector.put("keyword3", signupInfo.getInspectorName());// 工单处理人
        paramsInspector.put("remark", "点击前往验收成果！");
        paramsInspector.put("pagepath", "/pages_private_scene1/evaluation/acceptance_results?recordId="+ signupInfo.getId());// （链接到【验收页面】）
        paramsInspector.put("url", "/pages_private_scene1/evaluation/acceptance_results?recordId="+ signupInfo.getId() + "&readOnly=1");// （链接到【验收页面-只读】）
        paramsInspector.put("userid", signupInfo.getInspectorId());
        paramsInspector.put("docUnid", signupInfo.getId());
        paramsInspector.put("createdUserid", signupInfo.getInspectorId());
        return sendMsgToApplets(paramsInspector);
    }

    /**
     * 给参与者发送【任务回收】通知
     * @param signupInfo
     * @return
     */
    @Override
    public TimerTask recall(EvaluationSignup signupInfo) {
        // 公众号通知
        JSONObject paramsPartner = new JSONObject();
        paramsPartner.put("templateid", WORKER_PROGRESS_TIP);
        paramsPartner.put("first", "您参与的" + signupInfo.getSubject() + "评测任务，经两次返修仍不合格，已回收当前任务。");
        paramsPartner.put("keyword1", "NO."+ signupInfo.getTaskNumber());// 工单号
        paramsPartner.put("keyword2", "任务回收");// 工单进度
        paramsPartner.put("keyword3", signupInfo.getPartnerName());// 工单处理人
        paramsPartner.put("remark", "");
        paramsPartner.put("pagepath", "");
        paramsPartner.put("url", "");
        paramsPartner.put("userid", signupInfo.getPartnerId());
        paramsPartner.put("docUnid", signupInfo.getId());
        paramsPartner.put("createdUserid", signupInfo.getPartnerId());
        return sendMsgToApplets(paramsPartner);
    }

    /**
     * 给参与者发送【验收通过】通知
     * @param signupInfo
     * @param task
     * @return
     */
    @Override
    public TimerTask pass(EvaluationSignup signupInfo, EvaluationTask task) {

        String first = "您参与的" + signupInfo.getSubject() + "测评任务已通过验收，获得" + task.getReward() + "元测评报酬，感谢您的参与～";

        // 是否评级发放报酬。0:否；1:是；
        if("1".equals(task.getEnableRating())){
            first = "您提交的" + signupInfo.getSubject() + "的测评报告已验收，最终评级结果将在" + task.getEndTime() + "公布，若评为A或B等级，平台会自动补发额外报酬，感谢参与～";
        }

        // 公众号通知
        JSONObject paramsPartner = new JSONObject();
        paramsPartner.put("templateid", WORKER_PROGRESS_TIP);
        paramsPartner.put("first", first);
        paramsPartner.put("keyword1", "NO."+ signupInfo.getTaskNumber());// 工单号
        paramsPartner.put("keyword2", "通过验收");// 工单进度
        paramsPartner.put("keyword3", "平台通知");// 工单处理人
        paramsPartner.put("remark", "点击查看验收成果！");
        paramsPartner.put("pagepath", "/pages_private_scene1/evaluation/submit_results?docUnid="+ signupInfo.getId() + "&readOnly=1&userId=" + signupInfo.getPartnerId());// （链接到【拍档提交成果-只读】）
        paramsPartner.put("url", "/pages_private_scene1/evaluation/submit_results?docUnid="+ signupInfo.getId() + "&readOnly=1&userId=" + signupInfo.getPartnerId());// （链接到【拍档提交成果-只读】）
        paramsPartner.put("userid", signupInfo.getPartnerId());
        paramsPartner.put("docUnid", signupInfo.getId());
        paramsPartner.put("createdUserid", signupInfo.getPartnerId());
        return sendMsgToApplets(paramsPartner);
    }

    /**
     * 给参与者发送评级奖励通知（A级）
     * @param signupInfo
     * @param task
     * @return
     */
    @Override
    public TimerTask reissueA(EvaluationSignup signupInfo, EvaluationTask task) {

        double _rewardA = 0.00;
        // 计算【A级】需要补发的报酬
        if(task.getLevelAReward().compareTo(task.getLevelCReward()) > 0){
            _rewardA = task.getLevelAReward().doubleValue() - task.getLevelCReward().doubleValue();
        }

        // 公众号通知
        JSONObject paramsPartner = new JSONObject();
        paramsPartner.put("templateid", WORKER_PROGRESS_TIP);
        paramsPartner.put("first", "您在" + signupInfo.getSubject() + "测评任务中提交的测评报告，被评为 "+ signupInfo.getGrade() +"，共获得" + task.getLevelAReward() + "元测评报酬，平台将给您发放" + _rewardA + "元尾款，请查收！");
        paramsPartner.put("keyword1", "NO."+ signupInfo.getTaskNumber());// 工单号
        paramsPartner.put("keyword2", "测评奖励");// 工单进度
        paramsPartner.put("keyword3", "平台通知");// 工单处理人
        paramsPartner.put("remark", "点击查看收益详情。");
        paramsPartner.put("pagepath", "/pages/index/incomeIndex");// （链接到【收益页面】）
        paramsPartner.put("url", "/pages/index/incomeIndex");// （链接到【收益页面】）
        paramsPartner.put("userid", signupInfo.getPartnerId());
        paramsPartner.put("docUnid", signupInfo.getId());
        paramsPartner.put("createdUserid", signupInfo.getPartnerId());
        return sendMsgToApplets(paramsPartner);
    }

    /**
     * 给参与者发送评级奖励通知（B级）
     * @param signupInfo
     * @param task
     * @return
     */
    @Override
    public TimerTask reissueB(EvaluationSignup signupInfo, EvaluationTask task) {
        double _rewardB = 0.00;
        // 计算【B级】需要补发的报酬
        if(task.getLevelBReward().compareTo(task.getLevelCReward()) > 0){
            _rewardB = task.getLevelBReward().doubleValue() - task.getLevelCReward().doubleValue();
        }
        // 公众号通知
        JSONObject paramsPartner = new JSONObject();
        paramsPartner.put("templateid", WORKER_PROGRESS_TIP);
        paramsPartner.put("first", "您在" + signupInfo.getSubject() + "测评任务中提交的测评报告，被评为 "+ signupInfo.getGrade() +"，共获得" + task.getLevelAReward() + "元测评报酬，平台将给您发放" + _rewardB + "元尾款，请查收！");
        paramsPartner.put("keyword1", "NO."+ signupInfo.getTaskNumber());// 工单号
        paramsPartner.put("keyword2", "测评奖励");// 工单进度
        paramsPartner.put("keyword3", "平台通知");// 工单处理人
        paramsPartner.put("remark", "点击查看收益详情。");
        paramsPartner.put("pagepath", "/pages/index/incomeIndex");// （链接到【收益页面】）
        paramsPartner.put("url", "/pages/index/incomeIndex");// （链接到【收益页面】）
        paramsPartner.put("userid", signupInfo.getPartnerId());
        paramsPartner.put("docUnid", signupInfo.getId());
        paramsPartner.put("createdUserid", signupInfo.getPartnerId());
        return sendMsgToApplets(paramsPartner);
    }

    /**
     * 给参与者发送提醒提交成果通知
     * @param signupInfo
     * @param tag
     * @return
     */
    @Override
    public TimerTask reminder(EvaluationSignup signupInfo, String tag) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        // 计算剩余天数
        int diffDays = 0;
        String first = "";

        if("1".equals(tag)){
            // 评级开始时间(日期) - 今天(日期) <= 1天
            diffDays = (int) DateUtil.between(sdf.parse(signupInfo.getEndTime()), sdf.parse(DateUtil.now()), DateUnit.DAY, false);
            first = "距离您参与的" + signupInfo.getSubject() + "测评活动截止时间还剩最后" + diffDays + "天，请尽快提交测评成果，逾期将无法参与验收和评级，请知晓！（已提交，请忽略）！";

        } else if("2".equals(tag)){
            // 报名时间(日期) + 提交周期(天数) - 今天(日期) <= 1天
            diffDays = (int) DateUtil.between(DateUtils.addDays(sdf.parse(signupInfo.getCreateTime()), signupInfo.getSubmitLimitDays()), sdf.parse(DateUtil.now()), DateUnit.DAY, false);
            first = "您报名参与的" + signupInfo.getSubject() + "测评活动距离报告提交截止时间还有" + diffDays + "天，请尽快提交！逾时则名额作废。";
        } else if("3".equals(tag)){
            // 报名截止时间(日期) - 今天(日期) <= 3天
            diffDays = (int) DateUtil.between(sdf.parse(signupInfo.getJoinEndTime()), sdf.parse(DateUtil.now()), DateUnit.DAY, false);
            first = "您报名参与的" + signupInfo.getSubject() + "测评活动距离报告提交截止时间还有" + diffDays + "天，请尽快提交！逾时则名额作废。";
        }

        // 公众号通知
        JSONObject paramsPartner = new JSONObject();
        paramsPartner.put("templateid", WORKER_PROGRESS_TIP);
        paramsPartner.put("first", first);
        paramsPartner.put("keyword1", "NO."+ signupInfo.getTaskNumber());// 工单号
        paramsPartner.put("keyword2", "提交成果");// 工单进度
        paramsPartner.put("keyword3", signupInfo.getPartnerName());// 工单处理人
        paramsPartner.put("remark", "点击前往提交！");
        paramsPartner.put("pagepath", "/pages_private_scene1/evaluation/submit_results?docUnid="+ signupInfo.getId() + "&readOnly=1&userId=" + signupInfo.getPartnerId());// （链接到【拍档提交成果-只读】）
        paramsPartner.put("url", "/pages_private_scene1/evaluation/submit_results?docUnid="+ signupInfo.getId() + "&readOnly=1&userId=" + signupInfo.getPartnerId());// （链接到【拍档提交成果-只读】）
        paramsPartner.put("userid", signupInfo.getPartnerId());
        paramsPartner.put("docUnid", signupInfo.getId());
        paramsPartner.put("createdUserid", signupInfo.getPartnerId());
        return sendMsgToApplets(paramsPartner);
    }

    /**
     * 给参与者发送【超时任务回收】通知
     * @param signupInfo
     * @return
     */
    @Override
    public TimerTask timeoutRecall(EvaluationSignup signupInfo) {
        // 公众号通知
        JSONObject paramsPartner = new JSONObject();
        paramsPartner.put("templateid", WORKER_PROGRESS_TIP);
        paramsPartner.put("first", "由于您未在限定时间内提交成果，需要强制回收你的参与名额，为了不影响您的信用，下次参与评测任务时需要尽快提交成果！");
        paramsPartner.put("keyword1", "NO."+ signupInfo.getTaskNumber());// 工单号
        paramsPartner.put("keyword2", "任务作废");// 工单进度
        paramsPartner.put("keyword3", "平台通知");// 工单处理人
        paramsPartner.put("remark", "点击了解任务详情！持续关注公众号，接收更多工作机会。");
        paramsPartner.put("pagepath", "/pages/index/jobIndex");// 工作大厅
        paramsPartner.put("url", "/pages/index/jobIndex");// 工作大厅
        paramsPartner.put("userid", signupInfo.getPartnerId());
        paramsPartner.put("docUnid", signupInfo.getId());
        paramsPartner.put("createdUserid", signupInfo.getPartnerId());
        return sendMsgToApplets(paramsPartner);
    }

    /**
     * 给评级人员发送【评级】通知
     * @param task
     * @return
     */
    @Override
    public TimerTask rating(EvaluationTask task) {
        // 公众号通知
        JSONObject paramsPartner = new JSONObject();
        paramsPartner.put("templateid", WORKER_PROGRESS_TIP);
        paramsPartner.put("first", task.getSubject() + "测评任务已结束，请您根据参与者表现进行评级，确认评级后，根据评测师等级直接给参与者发放相应奖励。");
        paramsPartner.put("keyword1", "NO."+ task.getTaskNumber());// 工单号
        paramsPartner.put("keyword2", "任务结束");// 工单进度
        paramsPartner.put("keyword3", task.getInspectorName());// 工单处理人
        paramsPartner.put("remark", "点击了解任务详情！持续关注公众号，接收更多工作机会。");
        paramsPartner.put("pagepath", "/pages_private_scene1/evaluation/rating?docUnid=" + task.getId());// （链接到【评级页面】）
        paramsPartner.put("url", "/pages_private_scene1/evaluation/ranking_list?docUnid=" + task.getId());// （链接到【排行榜】）
        paramsPartner.put("userid", task.getRatingMemberId());
        paramsPartner.put("docUnid", task.getId());
        paramsPartner.put("createdUserid", task.getRatingMemberId());
        return sendMsgToApplets(paramsPartner);
    }

    /**
     * 给参与者发送【超时任务作废】通知
     * @param signupInfo
     * @return
     */
    @Override
    public TimerTask timeoutCancel(EvaluationSignup signupInfo) {
        // 公众号通知
        JSONObject paramsPartner = new JSONObject();
        paramsPartner.put("templateid", WORKER_PROGRESS_TIP);
        paramsPartner.put("first", "您参与的" + signupInfo.getSubject() + "测评活动报名截止时间已到，本次任务已作废！");
        paramsPartner.put("keyword1", "NO."+ signupInfo.getTaskNumber());// 工单号
        paramsPartner.put("keyword2", "任务作废");// 工单进度
        paramsPartner.put("keyword3", "平台通知");// 工单处理人
        paramsPartner.put("remark", "点击了解任务详情！持续关注公众号，接收更多工作机会。");
        paramsPartner.put("pagepath", "/pages/index/jobIndex");// 工作大厅
        paramsPartner.put("url", "/pages/index/jobIndex");// 工作大厅
        paramsPartner.put("userid", signupInfo.getPartnerId());
        paramsPartner.put("docUnid", signupInfo.getId());
        paramsPartner.put("createdUserid", signupInfo.getPartnerId());
        return sendMsgToApplets(paramsPartner);
    }

    /**
     * 给参与者发送【回收名额】通知
     * @param signupInfo
     * @return
     */
    @Override
    public TimerTask recyclingQuota(EvaluationSignup signupInfo) {

        // 公众号通知
        JSONObject paramsPartner = new JSONObject();
        paramsPartner.put("templateid", WORKER_PROGRESS_TIP);
        paramsPartner.put("first", "很抱歉，您的测评名额已回收，如有疑问请联系客服！");
        paramsPartner.put("keyword1", "NO."+ signupInfo.getTaskNumber());// 工单号
        paramsPartner.put("keyword2", "任务作废");// 工单进度
        paramsPartner.put("keyword3", "平台通知");// 工单处理人
        paramsPartner.put("remark", "点击了解任务详情！持续关注公众号，接收更多工作机会。");
        paramsPartner.put("pagepath", "/pages/index/jobIndex");// 工作大厅
        paramsPartner.put("url", "/pages/index/jobIndex");// 工作大厅
        paramsPartner.put("userid", signupInfo.getPartnerId());
        paramsPartner.put("docUnid", signupInfo.getId());
        paramsPartner.put("createdUserid", signupInfo.getPartnerId());
        return sendMsgToApplets(paramsPartner);
    }

    /**
     * 发送消息到小程序
     */
    private TimerTask sendMsgToApplets(JSONObject object) {
        JSONObject params = new JSONObject();
        params.put("templateid", object.getString("templateid"));
        params.put("first", object.getString("first"));
        params.put("keyword1", object.getString("keyword1"));
        params.put("keyword2", object.getString("keyword2"));
        params.put("keyword3", object.getString("keyword3"));
        params.put("keyword4", object.getString("keyword4"));
        params.put("keyword5", object.getString("keyword5"));
        params.put("keyword6", object.getString("keyword6"));
        params.put("remark", object.getString("remark"));
        params.put("pagepath", object.getString("pagepath"));
        params.put("url", object.getString("url"));
        params.put("userid", object.getString("userid"));
        params.put("docUnid", object.getString("docUnid"));
        params.put("createdUserid", object.getString("createdUserid"));
        return new TimerTask() {
            @Override
            public void run(){
                HttpResponse response = HttpRequest.post(sendMsgUri + "/msg/savemsg")
                        .header("Content-Type", "application/json")
                        .header("Accept", "application/json")
                        .header("sysid", sysId)
                        .header("syspwd", sysPwd)
                        .body(params.toJSONString())
                        // .form(params)
                        .execute();
                log.info("{}发送消息到小程序返回结果：{}", DateUtil.now(), response.body());
            }
        };
    }


}
